package com.example.demoweb.controller;

import com.example.demoweb.entity.Person;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.org.apache.bcel.internal.classfile.Code;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.SystemException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.UUID;

/**
 * @author 赵恒
 * @date 2023/6/25
 */
@RestController
@RequestMapping("file")
@Slf4j
public class FileController {
    ObjectMapper objectMapper = new ObjectMapper();
    String basedir = "D:\\temp\\demo\\web";

    @ApiOperation("上传单个文件")
    @PostMapping("/upload/single")
    public String uploadFile(MultipartFile file) {
        if (file == null) {
            return "上传文件为空";
        }
        return saveFile(file);
    }

    @ApiOperation(("上传单个文件和person-body（错误）"))
    @PostMapping("/upload/person")
    public String uploadFileAndPerson(MultipartFile file, @RequestBody Person person) {
        try {
            log.info("Person:{}", objectMapper.writeValueAsString(person));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        String fileName = saveFile(file);
        log.info("保存后的文件名：{}", fileName);
        return fileName;
    }

    @ApiOperation(("上传单个文件和person-string"))
    @PostMapping("/upload/personStr")
    public String uploadFileAndPersonString(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "personStr")String personStr) {
        Person person = null;
        try {
            person = objectMapper.readValue(personStr, Person.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        log.info("person:{}", person);
        String fileName = getFileStream(file);
        log.info("保存后的文件名：{}", fileName);
        return fileName;
    }

    @ApiOperation(("上传多个文件和person-string"))
    @PostMapping("/uploadFiles/personStr")
    public String uploadFilesAndPersonString(@RequestParam(value = "files") MultipartFile[] files,
                                             @RequestParam(value = "personStr")String personStr ) {
        Person person = null;
        try {
            person = objectMapper.readValue(personStr, Person.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        log.info("person:{}", person);

        for (MultipartFile file : files) {
            saveFile(file);
        }

        return "上传成功";
    }

    private String saveFile(MultipartFile file) {
        //1. 获取原始文件名
        String originalFilename = file.getOriginalFilename();
        log.info("文件名：{}", originalFilename);
        // 获取文件后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //2. 使用UUID重新生成文件名，防止文件名称重复造成文件覆盖
        String fileName = UUID.randomUUID() + suffix;
        //3. 创建一个目录对象
        File dir = new File(basedir);
        //4. 判断当前目录是否存在
        if (!dir.exists()) {
            //若目录不存在，需要创建
            dir.mkdirs();
        }
        //5. 将临时文件转存到指定位置
        try {
            file.transferTo(new File(basedir + File.separator + fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileName;
    }

    private String getFileStream(MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            File f = new File(basedir + File.separator + file.getOriginalFilename());
            return inputStream2File(inputStream, f);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file.getOriginalFilename();
    }


    /**
     * 将inputStream转化为file
     * @param is
     * @param file 要输出的文件目录
     */
    public String inputStream2File (InputStream is, File file) throws IOException {
        OutputStream os = null;
        try {
            os = new FileOutputStream(file);
            int len = 0;
            byte[] buffer = new byte[8192];

            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } finally {
            os.close();
            is.close();
        }
        return file.getName();
    }
}
